﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace HurSimLib
{
    /// <summary>
    /// A wrapper class for a pseudo-random number generator used to
    /// set the creation times of objects.
    /// </summary>
    public class HurObjectGenerator
    {
        //Creation time limits for the objects to be generated
        private DateTime m_initialtime;
        private DateTime m_endtime;
        /// <summary>
        /// The generator based on a random number distribution
        /// which will be used to set creation times of objects
        /// </summary>
        private Troschuetz.Random.Distribution m_distribution;
        /// <summary>
        /// The time unit to be used in genrating object creation times
        /// </summary>
        public TimeUnit GeneratorTimeUnit;
        /// <summary>
        /// The process which wil receive the objects after this one.
        /// </summary>
        private HurProcessBase m_nextprocess;

        /// <summary>
        /// The empty constructor starts with blank times
        /// </summary>

        public HurObjectGenerator()
        {
            m_initialtime = m_endtime = new DateTime(
               DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 0, 0, 0);
        }

        /// <summary>
        /// This constructor receives the underlying distribution as an argument
        /// </summary>
        /// <param name="gendist"></param>
        public HurObjectGenerator(Troschuetz.Random.Distribution gendist)
            : this()
        {
            m_distribution = gendist;
        }
        /// <summary>
        /// This property gets/sets the time of start for the object generation
        /// </summary>
        public DateTime GenerationStart
        {
            get { return m_initialtime; }
            set { m_initialtime = value; }
        }
        /// <summary>
        /// This property gets/sets the end time of the object generation
        /// </summary>
        public DateTime GenerationEnd
        {
            get { return m_endtime; }
            set { m_endtime = value; }
        }

        public HurProcessBase NextProcess
        {
            get { return m_nextprocess; }
            set { m_nextprocess = value; }
        }

        /// <summary>
        /// This property gets'sets the underlying random generation distribution
        /// </summary>
        public Troschuetz.Random.Distribution GeneratorDistribution
        {
            get { return m_distribution; }
            set { m_distribution = value; }
        }

        /// <summary>
        /// This function generates objects untila specified time and places
        /// them in the next process' queue.
        /// </summary>
        /// <param name="nextprocess">The process which will receive the created objects</param>
        public HurObject Generate()
        {
            double timeperiod;
            DateTime currenttime;
            HurObject newobject;
            currenttime = m_initialtime;

            while (currenttime < m_endtime)
            {
                timeperiod = m_distribution.NextDouble();
                currenttime = Common.NextTime(currenttime, timeperiod, GeneratorTimeUnit);
                newobject = new HurObject(currenttime);

                // Send the object to the next process.
                // The process will place the object in its procesing queue (if any).
                m_nextprocess.EnterObject(newobject);
                return newobject;
            }
            return null;
        }
    }
}
